package fdts.data.io;

/********************************************************
 * FDTS SS 2012. Calendar Layouter and iCalendar Imorter*
 * ******************************************************/

import static timeBench.data.TemporalDataset.PRIMITIVE_INTERVAL;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;

import net.fortuna.ical4j.model.Calendar;
import net.fortuna.ical4j.model.Component;
import net.fortuna.ical4j.model.DateTime;
import net.fortuna.ical4j.model.Period;
import net.fortuna.ical4j.model.PeriodList;

import timeBench.calendar.Granularity;
import timeBench.calendar.Granule;
import timeBench.calendar.JavaDateCalendarManager;
import timeBench.calendar.JavaDateCalendarManager.Granularities;
import timeBench.data.TemporalDataException;
import timeBench.data.TemporalDataset;
import timeBench.data.TemporalElement;
import timeBench.data.TemporalObject;

/**
 * this class is a parser that supports the VEVENT element of the iCalendarSpecification
 * nothing else is read in. the data are stored in a TemporalDataset
 * 
 * http://ical4j.sourceforge.net/introduction.html
 * 
 * @author agnieszka wojdecka and andreas hoermann
 *
 */
public class iCalendarParser{
	
	/**
	 * this methods reads in the VEVENT elements from the calendar and stores it
	 * in a TemporalDataset object with the summary and the starting- and endpoint of time.
	 * further xstart, xend and ystart, yend are calculated, the index in the calendar from 
	 * the CalendarVisualization application. the index depends on the granularity of the axis.
	 * 
	 * @param calendar the calendar from ical4j with all data from the ics file
	 * @param from starting point of period, in local time format (see iCalendar specification)
	 * @param to endpoint of period, in local time format (see iCalendar specification)
	 * @param xGranularity granularity of x axis
	 * @param yGranularity granularity of y axis
	 * @param today milliseconds of current time
	 * @return
	 * @throws TemporalDataException
	 */
	public TemporalDataset parse( Calendar calendar, DateTime from, DateTime to, Granularity xGranularity, Granularity yGranularity,long today) throws TemporalDataException{
		if(from.after(to))
			System.out.println( "attention: " + from + " " + to );
		
		if(calendar == null || from == null || to == null || from.after(to)) 
			return null;
		
		TemporalDataset data = new TemporalDataset();
		try {
			data.addDataColumn("summary", String.class, "");
			data.addDataColumn("xstart", float.class, -1);
			data.addDataColumn("xend", float.class, -1);
			data.addDataColumn("ystart", float.class, -1);
			data.addDataColumn("yend", float.class, -1);
		} catch (TemporalDataException e2) {
			e2.printStackTrace();
		}
		
		ArrayList<DateTime> times = split(from,to,xGranularity);
		
		for (int i = 0; i < times.size()-1; i++) {
			
			Period period = new Period(times.get(i), times.get(i+1));
			
			for (Object o : calendar.getComponents("VEVENT")) {
		    	Component c = (Component)o;
		    	PeriodList list = c.calculateRecurrenceSet(period);
	
		    	for (Object po : list) {
		    		Date start = null;
					Date end = null;
					Granule startGranule;
					Granule endGranule;
					Granule calstartGranule;
					Granule calendGranule;
					float granuleIdentifier1;
					float granuleIdentifier2;
					
		    		Period p = (Period)po;
		    		String str = p.toString(); // local time
		    		String str_start = str.substring(0,str.indexOf("/"));
		    		String str_end = str.substring(str.indexOf("/")+1,str.length());
		    		str_start = str_start.substring(0,str_start.indexOf("T")) + ":" + str_start.substring(str_start.indexOf("T")+1,str_start.length());
		    		str_end = str_end.substring(0,str_end.indexOf("T")) + ":" + str_end.substring(str_end.indexOf("T")+1,str_end.length());
		    		
					try {
						start = new SimpleDateFormat("yyyyMMdd:HHmmss").parse(str_start);
						end  = new SimpleDateFormat("yyyyMMdd:HHmmss").parse(str_end);
					} catch (ParseException e1) {
						e1.printStackTrace();
					}
		    		
					String summary = c.getProperties("SUMMARY").toString();
					summary = summary.substring(summary.indexOf(":")+1,summary.length());
					
					// build temporaldataset
					JavaDateCalendarManager manager = new JavaDateCalendarManager();
					int id1 = -1;
					int id2 = -1;
					if(xGranularity.getIdentifier() < yGranularity.getIdentifier()){
						id1 = xGranularity.getIdentifier(); 
						id2 = yGranularity.getIdentifier();
						xGranularity = new Granularity(xGranularity.getCalendar(),id1,yGranularity.getGranularityContextIdentifier());
						yGranularity = new Granularity(yGranularity.getCalendar(),id2,yGranularity.getGranularityContextIdentifier());
					} else {
						id1 = yGranularity.getIdentifier();
						id2 = xGranularity.getIdentifier();
						yGranularity = new Granularity(yGranularity.getCalendar(),id1,xGranularity.getGranularityContextIdentifier());
						xGranularity = new Granularity(xGranularity.getCalendar(),id2,xGranularity.getGranularityContextIdentifier());
					}
					
					// an interval
					startGranule = manager.createGranule(start, new Granularity(xGranularity.getCalendar(),0,id2));
					endGranule = manager.createGranule(end, new Granularity(xGranularity.getCalendar(),0,id2));
					
					GregorianCalendar cal = new GregorianCalendar();
					cal.setTimeInMillis(today);
					calstartGranule = manager.createGranule(cal.getTime(), xGranularity);
					calendGranule = manager.createGranule(cal.getTime(), xGranularity);
					
					TemporalElement te0 = data.addTemporalElement(startGranule.getInf(), endGranule.getSup(), 0, id2, PRIMITIVE_INTERVAL);
					TemporalObject o0 = data.addTemporalObject(te0.getId());
					o0.set("summary", summary);
					// start and end of axis
					granuleIdentifier1 = createCalendarAxisIndex(xGranularity,startGranule.getInf(),startGranule.getSup(),calstartGranule.getInf(),calstartGranule.getSup(),today,true);
					granuleIdentifier2 = createCalendarAxisIndex(xGranularity,endGranule.getInf(),endGranule.getSup(),calendGranule.getInf(),calendGranule.getSup(),today,false);
					o0.set("xstart", granuleIdentifier1);
					o0.set("xend", granuleIdentifier2);
					
					calstartGranule = manager.createGranule(cal.getTime(), yGranularity);
					calendGranule = manager.createGranule(cal.getTime(), yGranularity);
		
					granuleIdentifier1 = createCalendarAxisIndex(yGranularity,startGranule.getInf(),startGranule.getSup(),calstartGranule.getInf(),calstartGranule.getSup(),today,true);
					granuleIdentifier2 = createCalendarAxisIndex(yGranularity,endGranule.getInf(),endGranule.getSup(),calendGranule.getInf(),calendGranule.getSup(),today,false);
					o0.set("ystart", granuleIdentifier1);
					o0.set("yend", granuleIdentifier2);
		    	}
			}
		}
		
		return data;
	}
	
	/**
	 * splits a periods like described in the following: if the granularity of the
	 * x axis is day, the the period is split in a single day
	 * @param from starting point of period, in local time format (see iCalendar specification)
	 * @param to endpoint of period, in local time format (see iCalendar specification)
	 * @param xGranularity granularity of x axis
	 * @return ArrayList<DateTime> a list of pairs like from0,to0,from1,to1,...
	 */
	private ArrayList<DateTime> split(DateTime from, DateTime to, Granularity xGranularity){
		ArrayList<DateTime> times = new  ArrayList<DateTime>();
		GregorianCalendar from_cal = new GregorianCalendar();
		from_cal.setTimeInMillis(from.getTime());
		GregorianCalendar to_cal = new GregorianCalendar();
		to_cal.setTimeInMillis(to.getTime());
		
		if( xGranularity.getIdentifier() == Granularities.Hour.toInt() ){
			GregorianCalendar help_cal = new GregorianCalendar();
			if( from_cal.get(GregorianCalendar.HOUR_OF_DAY) != to_cal.get(GregorianCalendar.HOUR_OF_DAY) ){
				help_cal.setTimeInMillis(from_cal.getTimeInMillis());
				help_cal.set(GregorianCalendar.HOUR_OF_DAY, help_cal.get(GregorianCalendar.HOUR_OF_DAY) + 1);
				while( to_cal.get(GregorianCalendar.HOUR_OF_DAY) != help_cal.get(GregorianCalendar.HOUR_OF_DAY) ){
					DateTime from1 = new DateTime();
					DateTime to1 = new DateTime();
					from1.setTime(from_cal.getTimeInMillis());
					to1.setTime(help_cal.getTimeInMillis());
					times.add(from1);
					times.add(to1);
					help_cal.set(GregorianCalendar.HOUR_OF_DAY, help_cal.get(GregorianCalendar.HOUR_OF_DAY) + 1);
					from_cal.set(GregorianCalendar.HOUR_OF_DAY, from_cal.get(GregorianCalendar.HOUR_OF_DAY) + 1);
				}
				from_cal.set(GregorianCalendar.HOUR_OF_DAY, from_cal.get(GregorianCalendar.HOUR_OF_DAY) + 1);
				from.setTime(from_cal.getTimeInMillis());
				to.setTime(to_cal.getTimeInMillis());
			}
			times.add(from);
			times.add(to);
		} else if( xGranularity.getIdentifier() == Granularities.Day.toInt() ){
			GregorianCalendar help_cal = new GregorianCalendar();
			if( from_cal.get(GregorianCalendar.DAY_OF_MONTH) != to_cal.get(GregorianCalendar.DAY_OF_MONTH) ){
				help_cal.setTimeInMillis(from_cal.getTimeInMillis());
				help_cal.set(GregorianCalendar.DAY_OF_MONTH, help_cal.get(GregorianCalendar.DAY_OF_MONTH) + 1);
				while( to_cal.get(GregorianCalendar.DAY_OF_MONTH) != help_cal.get(GregorianCalendar.DAY_OF_MONTH) ){
					DateTime from1 = new DateTime();
					DateTime to1 = new DateTime();
					from1.setTime(from_cal.getTimeInMillis());
					to1.setTime(help_cal.getTimeInMillis());
					times.add(from1);
					times.add(to1);
					help_cal.set(GregorianCalendar.DAY_OF_MONTH, help_cal.get(GregorianCalendar.DAY_OF_MONTH) + 1);
					from_cal.set(GregorianCalendar.DAY_OF_MONTH, from_cal.get(GregorianCalendar.DAY_OF_MONTH) + 1);
				}
				from_cal.set(GregorianCalendar.DAY_OF_MONTH, from_cal.get(GregorianCalendar.DAY_OF_MONTH) + 1);
				from.setTime(from_cal.getTimeInMillis());
				to.setTime(to_cal.getTimeInMillis());
			}
			times.add(from);
			times.add(to);
			
		} else if( xGranularity.getIdentifier() == Granularities.Week.toInt() ){
			System.out.println( "just week of year are supported at split!" );
			GregorianCalendar help_cal = new GregorianCalendar();
			if( from_cal.get(GregorianCalendar.WEEK_OF_YEAR) != to_cal.get(GregorianCalendar.WEEK_OF_YEAR) ){
				help_cal.setTimeInMillis(from_cal.getTimeInMillis());
				help_cal.set(GregorianCalendar.WEEK_OF_YEAR, help_cal.get(GregorianCalendar.WEEK_OF_YEAR) + 1);
				while( to_cal.get(GregorianCalendar.WEEK_OF_YEAR) != help_cal.get(GregorianCalendar.WEEK_OF_YEAR) ){
					DateTime from1 = new DateTime();
					DateTime to1 = new DateTime();
					from1.setTime(from_cal.getTimeInMillis());
					to1.setTime(help_cal.getTimeInMillis());
					times.add(from1);
					times.add(to1);
					help_cal.set(GregorianCalendar.WEEK_OF_YEAR, help_cal.get(GregorianCalendar.WEEK_OF_YEAR) + 1);
					from_cal.set(GregorianCalendar.WEEK_OF_YEAR, from_cal.get(GregorianCalendar.WEEK_OF_YEAR) + 1);
				}
				from_cal.set(GregorianCalendar.WEEK_OF_YEAR, from_cal.get(GregorianCalendar.WEEK_OF_YEAR) + 1);
				from.setTime(from_cal.getTimeInMillis());
				to.setTime(to_cal.getTimeInMillis());
			}
			times.add(from);
			times.add(to);
		} else if( xGranularity.getIdentifier() == Granularities.Month.toInt() ){
			GregorianCalendar help_cal = new GregorianCalendar();
			if( from_cal.get(GregorianCalendar.MONTH) != to_cal.get(GregorianCalendar.MONTH) ){
				help_cal.setTimeInMillis(from_cal.getTimeInMillis());
				help_cal.set(GregorianCalendar.MONTH, help_cal.get(GregorianCalendar.MONTH) + 1);
				while( to_cal.get(GregorianCalendar.MONTH) != help_cal.get(GregorianCalendar.MONTH) ){
					DateTime from1 = new DateTime();
					DateTime to1 = new DateTime();
					from1.setTime(from_cal.getTimeInMillis());
					to1.setTime(help_cal.getTimeInMillis());
					times.add(from1);
					times.add(to1);
					help_cal.set(GregorianCalendar.MONTH, help_cal.get(GregorianCalendar.MONTH) + 1);
					from_cal.set(GregorianCalendar.MONTH, from_cal.get(GregorianCalendar.MONTH) + 1);
				}
				from_cal.set(GregorianCalendar.MONTH, from_cal.get(GregorianCalendar.MONTH) + 1);
				from.setTime(from_cal.getTimeInMillis());
				to.setTime(to_cal.getTimeInMillis());
			}
			times.add(from);
			times.add(to);
		} else if( xGranularity.getIdentifier() == Granularities.Year.toInt() ){
			GregorianCalendar help_cal = new GregorianCalendar();
			if( from_cal.get(GregorianCalendar.YEAR) != to_cal.get(GregorianCalendar.YEAR) ){
				help_cal.setTimeInMillis(from_cal.getTimeInMillis());
				help_cal.set(GregorianCalendar.YEAR, help_cal.get(GregorianCalendar.YEAR) + 1);
				while( to_cal.get(GregorianCalendar.YEAR) != help_cal.get(GregorianCalendar.YEAR) ){
					DateTime from1 = new DateTime();
					DateTime to1 = new DateTime();
					from1.setTime(from_cal.getTimeInMillis());
					to1.setTime(help_cal.getTimeInMillis());
					times.add(from1);
					times.add(to1);
					help_cal.set(GregorianCalendar.YEAR, help_cal.get(GregorianCalendar.YEAR) + 1);
					from_cal.set(GregorianCalendar.YEAR, from_cal.get(GregorianCalendar.YEAR) + 1);
				}
				from_cal.set(GregorianCalendar.YEAR, from_cal.get(GregorianCalendar.YEAR) + 1);
				from.setTime(from_cal.getTimeInMillis());
				to.setTime(to_cal.getTimeInMillis());
			}
			times.add(from);
			times.add(to);
		} else {
			System.out.println( "Granularity not supported at the moment for time split!" );
		}
		
		return times;
	}
	
	/**
	 * this methods creates the index xstart, ystart or xend, yend for the CalendarVisualization 
	 * application. the returned value gives the correct position of the given inf and sup of the 
	 * granul on the axis accordingly to the granularity-range.
	 * 
	 * @param granularity the granularity of the axis
	 * @param inf milliseconds of the starting point of the granul
	 * @param sup milliseconds of the endpoint of the granul
	 * @param calinf milliseconds of the starting point of the calendar view
	 * @param calsup milliseconds of the end point of the calendar view
	 * @param today milliseconds of the current time in the calendar
	 * @param begin if xstart, ystart then true else if xend, yend then false
	 * @return float the index, the value on the axis range
	 * @throws TemporalDataException
	 */
	private float createCalendarAxisIndex(Granularity granularity,long inf, long sup, long calinf, long calsup, long today, boolean begin) throws TemporalDataException{
		float result = -1;
		
		GregorianCalendar cal;
		GregorianCalendar cal1;
		switch(Granularities.fromInt(granularity.getIdentifier())) { // the axis granuarity
			case Hour:{
				switch(Granularities.fromInt(granularity.getGranularityContextIdentifier())) { // the granualrity of the view
					case Day:
						cal = new GregorianCalendar();
						cal1 = new GregorianCalendar();
						
						if(begin) {
							cal.setTimeInMillis(inf);
							cal1.setTimeInMillis(calinf);
						}
						else {
							cal.setTimeInMillis(sup);
							cal1.setTimeInMillis(calsup);
						}
						
						if(cal.get(GregorianCalendar.MONTH) == cal1.get(GregorianCalendar.MONTH) &&
						   cal.get(GregorianCalendar.YEAR) == cal1.get(GregorianCalendar.YEAR) &&
						   cal.get(GregorianCalendar.WEEK_OF_MONTH) == cal1.get(GregorianCalendar.WEEK_OF_MONTH) 
						   && cal.get(GregorianCalendar.DAY_OF_WEEK) == cal1.get(GregorianCalendar.DAY_OF_WEEK) ){
							
							result = cal.get(GregorianCalendar.HOUR_OF_DAY);
							result += (cal.get(GregorianCalendar.MINUTE)/60.0);
							result += (cal.get(GregorianCalendar.SECOND)/3600.0);
						}
						break;
					case Week: {
						cal = new GregorianCalendar();
						cal1 = new GregorianCalendar();
						
						if(begin) {
							cal.setTimeInMillis(inf);
							cal1.setTimeInMillis(calinf);
						}
						else {
							cal.setTimeInMillis(sup);
							cal1.setTimeInMillis(calsup);
						}
					
						if(cal.get(GregorianCalendar.MONTH) == cal1.get(GregorianCalendar.MONTH) &&
						   cal.get(GregorianCalendar.YEAR) == cal1.get(GregorianCalendar.YEAR) &&
						   cal.get(GregorianCalendar.WEEK_OF_MONTH) == cal1.get(GregorianCalendar.WEEK_OF_MONTH) ){
							
							result = cal.get(GregorianCalendar.HOUR_OF_DAY);
							result += (cal.get(GregorianCalendar.MINUTE)/60.0);
							result += (cal.get(GregorianCalendar.SECOND)/3600.0);
						} else {
							result = -1;
						}
						break;
					}
					case Month: {
						cal = new GregorianCalendar();
						cal1 = new GregorianCalendar();
						
						if(begin) {
							cal.setTimeInMillis(inf);
							cal1.setTimeInMillis(calinf);
						}
						else {
							cal.setTimeInMillis(sup);
							cal1.setTimeInMillis(calsup);
						}
						
						if(cal.get(GregorianCalendar.MONTH) == cal1.get(GregorianCalendar.MONTH) &&
						   cal.get(GregorianCalendar.YEAR) == cal1.get(GregorianCalendar.YEAR) ){
							
							result = cal.get(GregorianCalendar.HOUR_OF_DAY);
							result += (cal.get(GregorianCalendar.MINUTE)/60.0);
							result += (cal.get(GregorianCalendar.SECOND)/3600.0);
						}
						break;
					}
					case Year: {
						cal = new GregorianCalendar();
						cal1 = new GregorianCalendar();
						
						if(begin) {
							cal.setTimeInMillis(inf);
							cal1.setTimeInMillis(calinf);
						}
						else {
							cal.setTimeInMillis(sup);
							cal1.setTimeInMillis(calsup);
						}
						if(cal.get(GregorianCalendar.YEAR) == cal1.get(GregorianCalendar.YEAR) ){			
							result = cal.get(GregorianCalendar.HOUR_OF_DAY);
							result += (cal.get(GregorianCalendar.MINUTE)/60.0);
							result += (cal.get(GregorianCalendar.SECOND)/3600.0);
						}
						break;
					}
					default:{
						System.out.println( "Granularity not supported at the moment for index calculation." );
					}
				}
				break;
			}
			case Day:{
				switch(Granularities.fromInt(granularity.getGranularityContextIdentifier())) {
					case Week: {
						cal = new GregorianCalendar();
						cal1 = new GregorianCalendar();
						
						if(begin) {
							cal.setTimeInMillis(inf);
							cal1.setTimeInMillis(calinf);
						}
						else {
							cal.setTimeInMillis(sup);
							cal1.setTimeInMillis(calsup);
						}
						
						if(cal.get(GregorianCalendar.MONTH) == cal1.get(GregorianCalendar.MONTH) &&
						   cal.get(GregorianCalendar.YEAR) == cal1.get(GregorianCalendar.YEAR)
						     && cal.get(GregorianCalendar.WEEK_OF_MONTH) == cal1.get(GregorianCalendar.WEEK_OF_MONTH)){
							
							if(begin) cal.setTimeInMillis(inf);
							else cal.setTimeInMillis(sup);
							result = cal.get(GregorianCalendar.DAY_OF_WEEK);
							result -= 1;
							if(result == 0)
								result = 7;
							if(begin) 
								result -= 1;
						} else {
							result = -1;
						}
						break;
					}
					case Day: {
						cal = new GregorianCalendar();
						cal1 = new GregorianCalendar();
						
						if(begin) {
							cal.setTimeInMillis(inf);
							cal1.setTimeInMillis(calinf);
						}
						else {
							cal.setTimeInMillis(sup);
							cal1.setTimeInMillis(calsup);
						}
						
						if(cal.get(GregorianCalendar.MONTH) == cal1.get(GregorianCalendar.MONTH) &&
						   cal.get(GregorianCalendar.YEAR) == cal1.get(GregorianCalendar.YEAR) &&
						   cal.get(GregorianCalendar.DAY_OF_MONTH) == cal1.get(GregorianCalendar.DAY_OF_MONTH)){
							
							if(begin) result = 0;
							else result = 1;
						}
						break;
					}
					case Month: {
						cal = new GregorianCalendar();
						cal1 = new GregorianCalendar();
						
						if(begin) {
							cal.setTimeInMillis(inf);
							cal1.setTimeInMillis(calinf);
						}
						else {
							cal.setTimeInMillis(sup);
							cal1.setTimeInMillis(calsup);
						}
						
						if(cal.get(GregorianCalendar.MONTH) == cal1.get(GregorianCalendar.MONTH) &&
						   cal.get(GregorianCalendar.YEAR) == cal1.get(GregorianCalendar.YEAR) ){
							
							if(begin) cal.setTimeInMillis(inf);
							else cal.setTimeInMillis(sup);
							result = cal.get(GregorianCalendar.DAY_OF_WEEK);
							result -= 1;
							if(result == 0)
								result = 7;
							if(begin) 
								result -= 1;
						} else {
							result = -1;
						}
						
						break;
					}
					case Year: {
						cal = new GregorianCalendar();
						cal1 = new GregorianCalendar();
						
						if(begin) {
							cal.setTimeInMillis(inf);
							cal1.setTimeInMillis(calinf);
						}
						else {
							cal.setTimeInMillis(sup);
							cal1.setTimeInMillis(calsup);
						}
						
						if(cal.get(GregorianCalendar.YEAR) == cal1.get(GregorianCalendar.YEAR)){
							
							if(begin) cal.setTimeInMillis(inf);
							else cal.setTimeInMillis(sup);
							result = cal.get(GregorianCalendar.DAY_OF_MONTH);
							if(begin) result--;
						} else {
							result = -1;
						}
						break;
					}
					default:{
						System.out.println( "Granularity not supported at the moment for index calculation." );
					}
				}
				break;
			}
			case Week:{
				switch(Granularities.fromInt(granularity.getGranularityContextIdentifier())) {
					case Month: {
						cal = new GregorianCalendar();
						cal1 = new GregorianCalendar();
						
						if(begin) {
							cal.setTimeInMillis(inf);
							cal1.setTimeInMillis(today);
						}
						else {
							cal.setTimeInMillis(sup);
							cal1.setTimeInMillis(today);
						}
						if(cal.get(GregorianCalendar.YEAR) == cal1.get(GregorianCalendar.YEAR) &&
						   cal.get(GregorianCalendar.MONTH) == cal1.get(GregorianCalendar.MONTH)){
							result = cal.get(GregorianCalendar.WEEK_OF_MONTH);
							if(!begin) result++;
						} else {
							result = -1;
						}
						break;
						}
					case Year: {
						cal = new GregorianCalendar();
						cal1 = new GregorianCalendar();
						
						if(begin) {
							cal.setTimeInMillis(inf);
							cal1.setTimeInMillis(today);
						}
						else {
							cal.setTimeInMillis(sup);
							cal1.setTimeInMillis(today);
						}
						if(cal.get(GregorianCalendar.YEAR) == cal1.get(GregorianCalendar.YEAR)){
							result = cal.get(GregorianCalendar.WEEK_OF_MONTH);
							if(!begin) result++;
						} else {
							result = -1;
						}
						break;
						}
					default:{
						System.out.println( "Granularity not supported at the moment for index calculation." );
					}
				}
				break;
			}
			case Month: {
				switch(Granularities.fromInt(granularity.getGranularityContextIdentifier())) {
					case Year:{
						cal = new GregorianCalendar();
						cal1 = new GregorianCalendar();
						
						if(begin) {
							cal.setTimeInMillis(inf);
							cal1.setTimeInMillis(calinf);
						}
						else {
							cal.setTimeInMillis(sup);
							cal1.setTimeInMillis(calsup);
						}
						
						if(cal.get(GregorianCalendar.YEAR) == cal1.get(GregorianCalendar.YEAR)){
							result = cal.get(GregorianCalendar.MONTH)+1;
							if(begin) result--;
						} else {
							result = -1;
						}
						break;
					}
					default:{
						System.out.println( "Granularity not supported at the moment for index calculation." );
					}	
				}
			}
			break;
			default:{
				System.out.println( "Granularity not supported at the moment for index calculation." );
			}
		}
		
		return result;
	}
}